package org.jsbd.boss.task;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.dao.IDmChannelRetentDAO;
import org.jsbd.boss.dao.IRetentFilterDao;
import org.jsbd.boss.dao.IRetentLogDAO;
import org.jsbd.boss.domian.channel.*;
import org.jsbd.boss.enums.RetentStatusEnum;
import org.jsbd.boss.mq.KafkaMqManager;
import org.jsbd.boss.mq.LogProcessor;
import org.jsbd.boss.service.IChannelApkInfoService;
import org.jsbd.boss.service.IChannelRetentService;
import org.jsbd.boss.service.LogManager;
import org.jsbd.boss.service.impl.CacheParamManager;
import org.jsbd.boss.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Date;

/**
 * @desc
 * @Date 2018/10/26 14:54
 * @Author xupengcheng [xupengcheng@zhexinit.com]
 */
public class RetentUpdateTask implements Runnable, Serializable {

    public static final Logger logger = LoggerFactory.getLogger(RetentUpdateTask.class);

    private static final long serialVersionUID = 1L;

    private RetentTaskVo taskVo;

    public RetentUpdateTask(RetentTaskVo taskVo) {
        this.taskVo = taskVo;
    }


    @Override
    public void run() {
        RedisClient redisClient = SpringContextUtils.getBean("redisClient");
        String imsi = taskVo.getImsi();
        String mark = taskVo.getMark();
        IDmChannelRetentDAO dmChannelRetentDAO = SpringContextUtils.getBean(IDmChannelRetentDAO.class);
        String currentDate = taskVo.getCurrentDate();
        if (StringUtils.isBlank(currentDate)) {
            Object taskDay = redisClient.get(CacheKey.TASK_DAY + mark + imsi);
            if (taskDay == null) {
                logger.warn("添加任务失败 没有获取到天 {} {}", new Object[]{mark, imsi});
                return;
            }
            String currentDay = taskDay.toString();
            taskVo.setCurrentDate(currentDay);
            taskVo.setStatus(RetentStatusEnum.INIT.getType());
            dmChannelRetentDAO.insert(taskVo);
            Integer actionType = this.taskVo.getActionType();
            if (actionType != null) {
                RetentFilter retentFilter = new RetentFilter();
                retentFilter.setImsi(imsi);
                retentFilter.setMark(mark);
                retentFilter.setRd(Integer.parseInt(currentDay));
                retentFilter.setActionType(actionType);
                retentFilter.setExecTime(DateUtil.getPreSomeDateStr(1));
                SpringContextUtils.getBean(IRetentFilterDao.class).insertRetentFilter(retentFilter);
            }
            KafkaMqManager.simulatorSyncToQueue(this.taskVo);
            LogProcessor.getTM().addReturnTaskLog(currentDay, mark,taskVo.getMobile(),taskVo.getImsi(),true);

        } else {
            currentDate = currentDate.replace("-", "");
            taskVo.setCurrentDate(currentDate);
            taskVo.setStatus(RetentStatusEnum.FINISHED.getType());
            //先删除留存文件
            SpringContextUtils.getBean(IChannelRetentService.class).deleteUnuseFile(imsi, mark, currentDate);
            ChannelApkConfig apkConfig = SpringContextUtils.getBean(IChannelApkInfoService.class).selectChannelApkConfig(taskVo.getMark());
            boolean brushFlag = false;
            if (apkConfig != null) {
                brushFlag = recordBrush(taskVo.getImsi(), apkConfig.getId(), redisClient);
                recordFill(apkConfig);
            }
            if (brushFlag) {
                taskVo.setBrushTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
            }

            try {
                int count = dmChannelRetentDAO.updateRetent(taskVo);
                if (count < 1) {
                    logger.warn("更新留存文件不成功 {}", new Object[]{JSON.toJSONString(taskVo)});
                } else {
                    logger.warn("更新留存文件成功 [{}]", new Object[]{JSON.toJSONString(taskVo)});
                }
            } catch (Exception e) {
                logger.error("更新留存文件报错 [{}]", JSON.toJSONString(taskVo), e);
            }

            taskVo.setLogDay(DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd"));
            SpringContextUtils.getBean(IDmChannelRetentDAO.class).insertLog(taskVo);
            KafkaMqManager.simulatorSyncToQueue(taskVo);

            LogProcessor.getTM().addReturnTaskLog(taskVo.getLogDay(),mark,null,taskVo.getImsi(),false);
            LogProcessor.getTM().addChangeMarkLog(currentDate, mark, taskVo.getChangeMark());
        }
    }


    private void recordFill(ChannelApkConfig apkConfig) {
        if (apkConfig.getIsFill() != null && apkConfig.getIsFill() == 1) {
            String currentDate = taskVo.getCurrentDate();
            ApkRetentLogVo record = new ApkRetentLogVo();
            record.setImsi(taskVo.getImsi());
            record.setApkId(apkConfig.getId());
            record.setFile1Name(taskVo.getFile1Name());
            record.setFile2Name(taskVo.getFile2Name());
            record.setFile3Name(taskVo.getFile3Name());
            record.setSettingSystem(taskVo.getSettingSystem());
            record.setCurrentMonth(Integer.parseInt(DateFormatUtils.format(System.currentTimeMillis(), "yyyyMM")));
            record.setExecDay(Integer.parseInt(DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd")));
            record.setRetentMonth(Integer.parseInt(currentDate.substring(0, 6)));
            record.setRetentDay(Integer.parseInt(currentDate));
            record.setLoginType(taskVo.getLoginType());
            record.setPayMax(taskVo.getPayMax());
            record.setPayMin(taskVo.getPayMin());
            record.setPayRate(taskVo.getPayRate());
            SpringContextUtils.getBean(IRetentLogDAO.class).insert(record);
        }
    }

    /**
     * 拉活回传记录
     *
     * @param imsi
     * @param apkId
     */
    private boolean recordBrush(String imsi, Integer apkId, RedisClient redisClient) {

        if (recordBrush2(apkId, DateUtil.getCurrentDateStr(), imsi, redisClient)) {
            return true;
        }
        //隔天的
        if (recordBrush2(apkId, DateUtil.getPreSomeDay(2), imsi, redisClient)) {
            return true;
        }

        return false;
    }


    private boolean recordBrush2(Integer apkId, String currDay, String imsi, RedisClient redisClient) {
        String recordKey = CacheKey.BRUSHID_RECORD_KEY + currDay + imsi + apkId;
        Object brushIdAndCode = redisClient.get(recordKey);
        if (brushIdAndCode != null) {
            String expireTime = (String) SpringContextUtils.getBean(CacheParamManager.class).getParamValue("BRUSH_IMSI_RECORD_TIME");
            if (expireTime == null) {
                expireTime = "86400";
            }
            if (!redisClient.evalSetNx(CacheKey.RETENT_BRUSH_LOCK + currDay.toString() + imsi + apkId, Long.parseLong(expireTime))) {
                return true;
            }
            String[] bIdAndCode = brushIdAndCode.toString().split("-");
            String brushId = bIdAndCode[0];
            String brushCode = bIdAndCode[1];

            redisClient.evalHincrby(CacheKey.BRUSH_RECORD, currDay + brushId + "realExecTotal", 1);
            redisClient.evalHincrby(CacheKey.BRUSH_RECORD + currDay + brushId, brushCode + "-" + apkId.toString() + "realExecTotal", 1);
            redisClient.remove(recordKey);
            LogProcessor.getTM().addReturnLinkLog(currDay, brushId);
            return true;
        }
        return false;
    }
}
